package org.dtrd.modules.service.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dtrd.modules.service.entity.bean.ServiceCategoryInfo;
import org.dtrd.modules.service.entity.bean.ServiceDetail;
import org.dtrd.modules.service.entity.bean.ServiceListInfo;
import org.dtrd.modules.service.entity.po.DtrdEntRdService;
import org.dtrd.modules.service.entity.po.DtrdRlServicePackage;
import org.dtrd.modules.service.mapper.DtrdEntRdServiceMapper;
import org.dtrd.modules.service.service.IDtrdEntRdServiceCategoryService;
import org.dtrd.modules.service.service.IDtrdEntRdServiceService;
import org.dtrd.modules.service.service.IDtrdRlServicePackageService;
import org.dtrd.modules.util.ShiroUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;

/**
 * <p>
 * 服务套餐信息 服务实现类
 * </p>
 *
 * @author QR
 * @since 2021-11-19 18:52:54
 */
@DS("multi-datasource1")
@Service
public class DtrdEntRdServiceServiceImpl extends ServiceImpl<DtrdEntRdServiceMapper, DtrdEntRdService> implements IDtrdEntRdServiceService {

    @Autowired
    private IDtrdEntRdServiceCategoryService serviceCategoryService;
    @Autowired
    private IDtrdEntRdServiceService packageService;
    @Autowired
    private IDtrdRlServicePackageService servicePackageRlService;

    @Override
    public Map<Integer, String> getServiceIdToNameMap() {
        List<DtrdEntRdService> list = list();
        if (CollectionUtil.isNotEmpty(list)) {
            HashMap<Integer, String> map = new HashMap<>(list.size());
            for (DtrdEntRdService service : list) {
                map.put(service.getDataId(), service.getServiceName());
            }
            return map;
        }
        return null;
    }

    @Override
    public boolean saveOrUpdateServiceInfo(ServiceDetail serviceDetail) {
        DtrdEntRdService service = new DtrdEntRdService();
        if (serviceDetail.getDataId() == null) {
            service = service.init();
        }
        service = service.parseFromDto(serviceDetail);
        return this.saveOrUpdate(service);
    }

    @Override
    public boolean hasSameServiceName(Integer serviceId, String serviceName, String orgCode) {
        LambdaQueryWrapper<DtrdEntRdService> wrapper = Wrappers.lambdaQuery(DtrdEntRdService.class)
                .eq(DtrdEntRdService::getServiceName, serviceName)
                .eq(DtrdEntRdService::getOrgCode, orgCode);
        DtrdEntRdService queryService = getOne(wrapper);
        return queryService != null && !Objects.equals(queryService.getDataId(), serviceId);
    }

    @Override
    public ServiceDetail getServiceInfo(Integer serviceId) {
        LambdaQueryWrapper<DtrdEntRdService> queryWrapper = baseQueryWrapper()
                .eq(DtrdEntRdService::getDataId, serviceId)
                .eq(DtrdEntRdService::getOrgCode, ShiroUtil.getOrgCode());
        DtrdEntRdService service = this.getOne(queryWrapper);
        return Optional.ofNullable(service)
                .map(po -> new ServiceDetail().parseFromPo(po))
                .orElse(null);
    }

    @Override
    public boolean hasCategoryService(Integer categoryId) {
        LambdaQueryWrapper<DtrdEntRdService> queryWrapper = Wrappers.lambdaQuery(DtrdEntRdService.class)
                .eq(DtrdEntRdService::getServiceCategoryId, categoryId);
        return CollectionUtil.isNotEmpty(list(queryWrapper));
    }

    @Override
    public List<ServiceListInfo> getServiceList(Integer packageId) {
        LambdaQueryWrapper<DtrdEntRdService> queryWrapper = baseQueryWrapper()
                .orderByDesc(DtrdEntRdService::getServiceCategoryId);
        // 设置搜索条件: 机构
        String orgCode = ShiroUtil.getOrgCode();
        if (StrUtil.isNotBlank(orgCode)) {
            queryWrapper.eq(DtrdEntRdService::getOrgCode, orgCode);
        }
        List<DtrdEntRdService> poList = this.list(queryWrapper);
        List<ServiceListInfo> dtoList = new ArrayList<>(poList.size());
        if (CollectionUtil.isNotEmpty(poList)) {
            // 获取 服务分类id : 服务分类名字 的映射
            Map<Integer, String> id2CategoryName = serviceCategoryService.getServiceCategoryList().stream()
                    .collect(groupingBy(ServiceCategoryInfo::getDataId, mapping(ServiceCategoryInfo::getCategoryName, joining())));
            dtoList = poList.stream()
                    .map(po -> {
                        ServiceListInfo serviceListInfo = new ServiceListInfo().parseFromPo(po);
                        // 设置 serviceCategoryName
                        serviceListInfo.setServiceCategoryName(id2CategoryName.get(po.getServiceCategoryId()));
                        return serviceListInfo;
                    })
                    .collect(Collectors.toList());
        }
        // 设置服务周期和服务次数
        if (packageId != null) {
            LambdaQueryWrapper<DtrdRlServicePackage> servicePackageQueryWrapper = Wrappers.lambdaQuery(DtrdRlServicePackage.class)
                    .eq(DtrdRlServicePackage::getPackageId, packageId);
            List<DtrdRlServicePackage> list = servicePackageRlService.list(servicePackageQueryWrapper);
            if (CollectionUtil.isNotEmpty(list)) {
                for (DtrdRlServicePackage servicePackageRl : list) {
                    Optional<ServiceListInfo> any = dtoList.stream()
                            .filter(dto -> Objects.equals(dto.getDataId(), servicePackageRl.getServiceId()))
                            .findAny();
                    if (any.isPresent()) {
                        ServiceListInfo serviceListInfo = any.get();
                        String serviceMonth = servicePackageRl.getServiceMonth();
                        // 服务周期
                        serviceListInfo.setServiceMonth(serviceMonth);
                        // 服务次数
                        serviceListInfo.setServiceCount(servicePackageRl.getServiceCount());
                        // 是否属于服务包标记
                        serviceListInfo.setFlag(servicePackageRl.isFlag());
                    }
                }
            }
        }
        return dtoList;
    }

    @Override
    public List<ServiceListInfo> getServiceList(Integer packageId, String orgCode) {
        LambdaQueryWrapper<DtrdEntRdService> queryWrapper = baseQueryWrapper()
                .orderByDesc(DtrdEntRdService::getServiceCategoryId)
                .eq(StringUtils.isNotBlank(orgCode),
                        DtrdEntRdService::getOrgCode, orgCode);
        List<DtrdEntRdService> poList = this.list(queryWrapper);
        List<ServiceListInfo> dtoList = new ArrayList<>(poList.size());
        if (CollectionUtil.isNotEmpty(poList)) {
            // 获取 服务分类id : 服务分类名字 的映射
            Map<Integer, String> id2CategoryName = serviceCategoryService.getServiceCategoryList().stream()
                    .collect(groupingBy(ServiceCategoryInfo::getDataId, mapping(ServiceCategoryInfo::getCategoryName, joining())));
            dtoList = poList.stream()
                    .map(po -> {
                        ServiceListInfo serviceListInfo = new ServiceListInfo().parseFromPo(po);
                        // 设置 serviceCategoryName
                        serviceListInfo.setServiceCategoryName(id2CategoryName.get(po.getServiceCategoryId()));
                        return serviceListInfo;
                    })
                    .collect(Collectors.toList());
        }
        // 设置服务周期和服务次数
        if (packageId != null) {
            LambdaQueryWrapper<DtrdRlServicePackage> servicePackageQueryWrapper = Wrappers.lambdaQuery(DtrdRlServicePackage.class)
                    .eq(DtrdRlServicePackage::getPackageId, packageId);
            List<DtrdRlServicePackage> list = servicePackageRlService.list(servicePackageQueryWrapper);
            if (CollectionUtil.isNotEmpty(list)) {
                for (DtrdRlServicePackage servicePackageRl : list) {
                    Optional<ServiceListInfo> any = dtoList.stream()
                            .filter(dto -> Objects.equals(dto.getDataId(), servicePackageRl.getServiceId()))
                            .findAny();
                    if (any.isPresent()) {
                        ServiceListInfo serviceListInfo = any.get();
                        String serviceMonth = servicePackageRl.getServiceMonth();
                        // 服务周期
                        serviceListInfo.setServiceMonth(serviceMonth);
                        // 服务次数
                        serviceListInfo.setServiceCount(servicePackageRl.getServiceCount());
                        // 是否属于服务包标记
                        serviceListInfo.setFlag(servicePackageRl.isFlag());
                    }
                }
            }
        }
        return dtoList;
    }

    @Override
    public boolean removeService(Integer serviceId) {
        // 删除服务套餐表中数据
        boolean result = this.removeById(serviceId);
        // 删除服务包和服务套餐关系表中数据
        LambdaQueryWrapper<DtrdRlServicePackage> deleteWrapper = Wrappers.lambdaQuery(DtrdRlServicePackage.class)
                .eq(DtrdRlServicePackage::getServiceId, serviceId);
        servicePackageRlService.remove(deleteWrapper);
        return result;
    }

    @Override
    public String getServiceName(Integer serviceId) {
        DtrdEntRdService service = getById(serviceId);
        return Optional.ofNullable(service).map(DtrdEntRdService::getServiceName).orElse(null);
    }

    @Override
    public String getServiceExecutorsByServiceDetailId(Integer serviceDetailId) {
        return baseMapper.selectServiceExecutorsByServiceDetailId(serviceDetailId);
    }

    private LambdaQueryWrapper<DtrdEntRdService> baseQueryWrapper() {
        return Wrappers.lambdaQuery(DtrdEntRdService.class).eq(DtrdEntRdService::getIsDel, 0);
    }
}
